package com.qkl.xiatang.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qkl.xiatang.app.dto.BusinessDTO;
import com.qkl.xiatang.app.dto.user.CompanyDTO;
import com.qkl.xiatang.app.dto.user.UserOutDTO;
import com.qkl.xiatang.app.dto.user.UserRegisterInDTO;
import com.qkl.xiatang.app.entity.CompanyEntity;
import com.qkl.xiatang.app.entity.user.AppUserCompanyEntity;
import com.qkl.xiatang.app.entity.user.AppUserInfo;
import com.qkl.xiatang.app.entity.sms.SmsOutDTO;
import com.qkl.xiatang.app.mapper.AppUserCompanyMapper;
import com.qkl.xiatang.app.mapper.AppUserInfoMapper;
import com.qkl.xiatang.app.mapper.CompanyMapper;
import com.qkl.xiatang.app.utils.*;
import com.qkl.xiatang.app.utils.appenum.AppUserDutiesEnum;
import com.qkl.xiatang.app.utils.appenum.AppUserStatus;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class AppUserInfoService {

    @Autowired
    private AppUserInfoMapper userInfoMapper;

    @Autowired
    private SmsDynamicService smsService;

    @Autowired
    private CryptoService cryptoService;

    @Autowired
    private AppUserCompanyMapper appUserCompanyMapper;

    @Autowired
    private ConfigService configService;

    @Autowired
    private CompanyMapper companyMapper;

    @Autowired
    private AppUserIdentityService appUserIdentityService;

    public AppUserInfo queryUser(String userId){
        return this.setUserIdentity(userInfoMapper.selectById(userId));
    }

    public AppUserInfo queryUserByPhone(String phone){
        List<AppUserInfo> list = this.queryUserListByPhone(phone);
        if(ObjectUtils.isNotEmpty(list)){
            return this.setUserIdentity(list.get(0));
        }
        return null;
    }

    public List<AppUserInfo> queryUserListByPhone(String phone){
        return userInfoMapper.selectList(new QueryWrapper<AppUserInfo>().eq("phone",phone));
    }

    /**
     *
     * @param account 账号或手机号码
     * @return
     */
    public AppUserInfo queryUserByAccount(String account){
        List<AppUserInfo> list = userInfoMapper.selectList(new QueryWrapper<AppUserInfo>().eq("phone",account).or().eq("username",account));
        if(ObjectUtils.isNotEmpty(list)){
            return this.setUserIdentity(list.get(0));
        }
        return null;
    }


    public String addUser(AppUserInfo user){
        Date date = new Date();
        user.setCreateTime(date);
        user.setUpdateTime(date);
        if(StringUtils.isEmpty(user.getName())){
            user.setName(AppUtils.genNickname());
        }
        userInfoMapper.insert(user);
        return user.getId();
    }

    public void updateUserById(AppUserInfo user){
        userInfoMapper.updateById(user);
    }

    /**
     * 用户注册
     * @param registerDTO
     * @return
     */
    public BusinessDTO<Object> userRegister(UserRegisterInDTO registerDTO){
        String mobile = registerDTO.getMobile();
        String verifyCode = registerDTO.getVerifyCode();
        String inpwd = registerDTO.getPwd();
        String companyId = "";
        String companyApply = registerDTO.getCompanyId();
        String name = registerDTO.getName();
        List<CompanyEntity> companyEntities = companyMapper.selectList(null);
        if(ObjectUtils.isEmpty(companyEntities)){
            return BusinessDTO.failBusiness("无公司");
        }
        boolean isExistCompany = false;
        for(CompanyEntity companyEntity : companyEntities){
            if(companyEntity.testCompany()){
                companyId = companyEntity.getId();
            }
            if(StringUtils.isEmpty(companyApply) && companyEntity.defaultCompany()){
                companyApply = companyEntity.getId();
            }
            if(companyEntity.getId().equals(companyId)){
                isExistCompany = true;
            }
        }
        if( !isExistCompany){
            return BusinessDTO.failBusiness("未设置测试公司或不存在该公司");
        }
        BusinessDTO<SmsOutDTO>  businessDTO  = smsService.verifySms(mobile,verifyCode);
        if(!businessDTO.isSucess()){
            return BusinessDTO.failBusiness(businessDTO.getMessage());
        }
        AppUserInfo queryUser = this.queryUserByPhone(mobile);
        if(null != queryUser && !queryUser.statusCancel()){
            return BusinessDTO.failBusiness("手机号[" + mobile + "]已注册");
        }
        String decryptPwd = cryptoService.decrypt(inpwd);//解密
        if(StringUtils.isEmpty(decryptPwd)){
            return BusinessDTO.failBusiness("密码解密错误");
        }
        if(null == queryUser) {
            AppUserInfo addUser = new AppUserInfo();
            addUser.setPhone(mobile);
            addUser.setUsername(mobile);
            addUser.setCompanyId(companyId);
            addUser.setCompanyApply(companyApply);
            addUser.setName(name);
            this.addUser(addUser);

            String userId = addUser.getId();
            String token = AppTokenUtils.encryptUserId(userId);
            String salt = AppUtils.randomChars(8);
            String pwd = PwdUtils.encrypt(userId, decryptPwd, salt);
            AppUserInfo updUser = new AppUserInfo();
            updUser.setId(userId);
            updUser.setPassword(pwd);
            updUser.setSalt(salt);
            updUser.setToken(token);
            updUser.setAvatar(configService.getAppUserImage());
            updUser.setIdentity(AppUserDutiesEnum.FEED.getDuties());
            this.updateUserById(updUser);
        }else {
            String userId = queryUser.getId();
            if(StringUtils.isEmpty(name)){
                name = queryUser.getName();
            }
            if(StringUtils.isEmpty(name)){
                name = AppUtils.genNickname();
            }
            Date date = new Date();
            String token = AppTokenUtils.encryptUserId(userId);
            String salt = AppUtils.randomChars(8);
            String pwd = PwdUtils.encrypt(userId, decryptPwd, salt);
            AppUserInfo updUser = new AppUserInfo();
            updUser.setId(userId);
            updUser.setName(name);
            updUser.setPassword(pwd);
            updUser.setSalt(salt);
            updUser.setToken(token);
            updUser.setStatus(AppUserStatus.APPLY.getStatus());
            updUser.setIdentity(AppUserDutiesEnum.FEED.getDuties());
            updUser.setCompanyId(companyId);
            updUser.setCompanyApply(companyApply);
            updUser.setCreateTime(date);
            updUser.setUpdateTime(date);
            this.updateUserById(updUser);
        }
        return BusinessDTO.sucessBusiness(new HashMap<>(),"注册用户成功");
    }

    /**
     * 注消用户
     * @return
     */
    public BusinessDTO<Object> userCancel(){
        String userId = AppSessionUtils.getUserId();
        AppUserInfo updUser = new AppUserInfo();
        updUser.setId(userId);
        updUser.setStatus(AppUserStatus.CANCEL.getStatus());
        this.updateUserById(updUser);
        appUserCompanyMapper.delete(new QueryWrapper<AppUserCompanyEntity>().eq("app_user_id",userId));
        return BusinessDTO.sucessBusiness(new HashMap<>(),"注消用户");
    }

    /**
     * 密码登陆
     * @param account 账号或手机号码
     * @param pwd
     * @param deviceId 设备id
     * @return
     */
    public BusinessDTO<UserOutDTO> userPwdLogin(String account,String pwd,String deviceId){
        AppUserInfo userInfo = this.queryUserByAccount(account);
        if(null == userInfo ){
            return BusinessDTO.failBusiness("用户未注册");
        }
        if( !AppUserStatus.isOK(userInfo.getStatus())){
            return BusinessDTO.failBusiness("用户" + AppUserStatus.getName(userInfo.getStatus()));
        }
        if(userInfo.delete()){
            return BusinessDTO.failBusiness("用户已删除");
        }
//        String decryptPwd = cryptoService.decrypt(pwd);//解密
//        if(StringUtils.isEmpty(decryptPwd)){
//            return BusinessDTO.failBusiness("密码解密错误");
//        }
//
//        String dbPwd = userInfo.getPassword();
//        String encryptPwd = PwdUtils.encrypt(userInfo.getId(),decryptPwd,userInfo.getSalt());
//        if(StringUtils.isAnyEmpty(dbPwd,encryptPwd) || !dbPwd.equals(encryptPwd)){
//            return BusinessDTO.failBusiness("密码错误");
//        }
        userInfo.setDeviceId(deviceId);
        userInfo.setToken("");
        this.setUserOtherInfo(userInfo);
        return BusinessDTO.sucessBusiness(copyUserDTO(userInfo),"登陆成功");
    }

    /**
     * 手机验证码登陆
     * @param mobile
     * @param verifyCode
     * @return
     */
    public BusinessDTO<UserOutDTO> userVerifyLogin(String mobile,String verifyCode,String deviceId){
        AppUserInfo querUser = this.queryUserByPhone(mobile);
        if(null == querUser){
            return BusinessDTO.failBusiness("手机号[" + mobile + "]未注册");
        }
        if( !AppUserStatus.isOK(querUser.getStatus())){
            return BusinessDTO.failBusiness("用户" + AppUserStatus.getName(querUser.getStatus()));
        }
        if(querUser.delete()){
            return BusinessDTO.failBusiness("用户已删除");
        }
        BusinessDTO<SmsOutDTO>  businessDTO  = smsService.verifySms(mobile,verifyCode);
        if(!businessDTO.isSucess()){
            return BusinessDTO.failBusiness(businessDTO.getMessage());
        }
        querUser.setDeviceId(deviceId);
        querUser.setToken("");
        this.setUserOtherInfo(querUser);
        return BusinessDTO.sucessBusiness(copyUserDTO(querUser),"登陆成功");
    }

    /**
     * 获取用户信息
     * @return
     */
    public BusinessDTO<UserOutDTO> getAppUserInfo(){
        AppUserInfo userInfo = AppSessionUtils.getSessionUser();
        userInfo.setCompanyList(this.queryUserCompanyList(userInfo.getId(),null));
        return BusinessDTO.sucessBusiness(copyUserDTO(userInfo),"用户信息");
    }


    /**
     * 忘记密码重置
     * @param mobile
     * @param verifyCode
     * @param pwd 新密码
     * @return
     */
    public BusinessDTO<Object> resetPwd(String mobile,String verifyCode,String pwd){
        AppUserInfo querUser = this.queryUserByPhone(mobile);
        if(null == querUser){
            return BusinessDTO.failBusiness("手机号[" + mobile + "]未注册");
        }
        BusinessDTO<SmsOutDTO>  businessDTO  = smsService.verifySms(mobile,verifyCode);
        if(!businessDTO.isSucess()){
            return BusinessDTO.failBusiness(businessDTO.getMessage());
        }
        String userId = querUser.getId();
        String newPwd = PwdUtils.encrypt(userId,pwd,querUser.getSalt());
        AppUserInfo updUser = new AppUserInfo();
        updUser.setId(userId);
        updUser.setPassword(newPwd);
        this.updateUserById(updUser);
        return BusinessDTO.sucessBusiness(new HashMap<>(),"密码重置成功");
    }

    /**
     * 退出登陆
     * @return
     */
    public BusinessDTO<Object> userLogout(){
        AppUserInfo session = AppSessionUtils.getSessionUser();
        if(null == session ){
            return BusinessDTO.failBusiness("用户未登陆");
        }
        AppUserInfo updUser = new AppUserInfo();
        updUser.setId(session.getId());
        updUser.setToken("");
        updUser.setDeviceId("");
        this.updateUserById(updUser);
        return BusinessDTO.sucessBusiness(new HashMap<>(),"退出登陆");
    }

    /**
     * 设置中心
     * @param name
     * @param mobile
     * @param verifyCode
     * @return
     */
    public BusinessDTO<Object> setUserInfo(String name,String mobile,String avatar,String verifyCode){
        AppUserInfo session = AppSessionUtils.getSessionUser();
        if(null == session ){
            return BusinessDTO.failBusiness("用户未登陆");
        }
        String phone = null;
        if(StringUtils.isNotEmpty(mobile)){
            List<AppUserInfo> users = this.queryUserListByPhone(mobile);
            if(ObjectUtils.isNotEmpty(users)){
                for(AppUserInfo user: users){
                    if(user.getId().equals(session.getId())){
                        continue;
                    }
                    return BusinessDTO.failBusiness("此手机号已存在，不能使用");
                }
            }
            BusinessDTO<SmsOutDTO>  businessDTO  = smsService.verifySms(mobile,verifyCode);
            if(!businessDTO.isSucess()){
                return BusinessDTO.failBusiness(businessDTO.getMessage());
            }
            phone = mobile;
        }
        if(StringUtils.isEmpty(name)){
            name = null;
        }
        if(StringUtils.isEmpty(avatar)){
            avatar = null;
        }
        AppUserInfo updUser = new AppUserInfo();
        updUser.setId(session.getId());
        updUser.setName(name);
        updUser.setPhone(phone);
        updUser.setAvatar(avatar);
        this.updateUserById(updUser);

        if(StringUtils.isNotEmpty(mobile)){
            session.setPhone(mobile);
        }
        if(StringUtils.isNotEmpty(name)){
            session.setName(name);
        }
        if(StringUtils.isNotEmpty(avatar)){
            session.setAvatar(avatar);
        }
        session.setCompanyList(this.queryUserCompanyList(session.getId(),null));
        return BusinessDTO.sucessBusiness(copyUserDTO(session),"设置成功");
    }

    /**
     * 查询用户公司
     * @return
     */
    public List<CompanyDTO> queryUserCompanyInfo(String keywords){
        List<CompanyDTO> companyList = this.queryUserCompanyList(keywords);
        if(ObjectUtils.isEmpty(companyList)){
            return new ArrayList<>();
        }
        return companyList;
    }

    /**
     * 切换用户公司
     * @param companyId
     * @return
     */
    public BusinessDTO<Object> switchUserCompany(String companyId){
        AppUserInfo session = AppSessionUtils.getSessionUser();
        if(null == session ){
            return BusinessDTO.failBusiness("用户未登陆");
        }
        companyId = StringUtils.trimToEmpty(companyId);
        if(StringUtils.isEmpty(companyId)){
            return BusinessDTO.failBusiness("切换公司id不能为空");
        }
        if(companyId.equals(AppSessionUtils.getCompanyId())){
            return BusinessDTO.failBusiness("同一公司无须切换");
        }
        List<CompanyDTO> companyList = this.queryUserCompanyList(session.getId(),null);
        if(ObjectUtils.isEmpty(companyList)){
            return BusinessDTO.failBusiness("无公司可切换");
        }
        String newCompanyId = null;
        for(CompanyDTO companyDTO : companyList){
            if(companyDTO.statusOK() && companyDTO.getId().equals(companyId)){
                newCompanyId = companyId;
                break;
            }
        }
        if(StringUtils.isEmpty(newCompanyId)){
            return BusinessDTO.failBusiness("无可切换的公司");
        }

        AppUserInfo updUser = new AppUserInfo();
        updUser.setId(session.getId());
        updUser.setCompanyId(companyId);
        this.updateUserById(updUser);

        session.setCompanyId(companyId);
        session.setCompanyList(companyList);
        return BusinessDTO.sucessBusiness(copyUserDTO(session),"切换公司成功");
    }

    /**
     * 查询公司
     * @param keywords
     * @return
     */
    public  List<CompanyDTO> queryCompanyList(String keywords){
        return this.queryCompanyList(null,keywords);
    }

    public  List<CompanyDTO> queryCompanyList(String companyId,String keywords){
        return userInfoMapper.queryCompanyList(companyId,keywords);
    }


    public List<AppUserCompanyEntity> queryUserJoinCompanyList(String userId,String companyId){
        QueryWrapper<AppUserCompanyEntity> queryWrapper = new QueryWrapper();
        if(StringUtils.isNotEmpty(userId)){
            queryWrapper.eq("app_user_id",userId);
        }
        if(StringUtils.isNotEmpty(companyId)){
            queryWrapper.eq("company_id",companyId);
        }
        return appUserCompanyMapper.selectList(queryWrapper);
    }

    public AppUserCompanyEntity queryUserJoinCompany(String userId,String companyId){
        List<AppUserCompanyEntity> list = this.queryUserJoinCompanyList(userId,companyId);
        if(ObjectUtils.isEmpty(list)){
            return null;
        }
        return list.get(0);
    }

    /**
     * 用户附加信息
     * @param additInfo
     */
    public BusinessDTO<Object> userAdditInfo(Map<String,Object> additInfo){
        if(ObjectUtils.isEmpty(additInfo)){
            return BusinessDTO.failBusiness("用户附加信息为空");
        }
        String userId = AppSessionUtils.getUserId();
        AppUserInfo updUser = new AppUserInfo();
        updUser.setId(userId);
        updUser.setAdditInfo(JSON.toJSONString(additInfo));
        userInfoMapper.updateById(updUser);
        return BusinessDTO.sucessBusiness(new HashMap<>(),"用户附加信息");
    }



    private List<CompanyDTO> queryUserCompanyList(String userId,String keywords){
        return userInfoMapper.queryUserCompany(userId,keywords);
    }

    private List<CompanyDTO> queryUserCompanyList(String keywords){
        return this.queryUserCompanyList(AppSessionUtils.getUserId(),keywords);
    }

    private List<CompanyDTO> queryUserCompanyList(){
        return this.queryUserCompanyList(AppSessionUtils.getUserId(),null);
    }


    private void setUserOtherInfo(AppUserInfo userInfo){
        String userId = userInfo.getId();
        String token = userInfo.getToken();
        String deviceId = userInfo.getDeviceId();
        token = StringUtils.isEmpty(token) ?  AppTokenUtils.encryptUserId(userId): null;
        deviceId = StringUtils.isEmpty(deviceId) ?  null: deviceId;

        String name = userInfo.getName();
        name = StringUtils.isEmpty(name) ?  AppUtils.genNickname(): null;
        if( null != token || null != name || null != deviceId){
            AppUserInfo updUser = new AppUserInfo();
            updUser.setId(userId);
            updUser.setToken(token);
            updUser.setName(name);
            updUser.setDeviceId(deviceId);
            this.updateUserById(updUser);

            if(null != token){
                userInfo.setToken(token);
            }
            if(null != name){
                userInfo.setName(name);
            }
        }
        userInfo.setCompanyList(this.queryUserCompanyList(userId,null));
    }

    /**
     * 从 app_user_company 表取身份
     * @param userInfo
     * @return
     */
    private AppUserInfo setUserIdentity(AppUserInfo userInfo){
        if(null == userInfo){
            return null;
        }
        userInfo.setIdentity(AppUserDutiesEnum.FEED.getDuties());

        /**
        AppUserCompanyEntity userCompany = this.queryUserJoinCompany(userInfo.getId(),userInfo.getCompanyId());
        if(null != userCompany){
            String identity = StringUtils.trimToEmpty(userCompany.getIdentity());
            if(StringUtils.isNotEmpty(identity)){
                userInfo.setIdentity(identity);
            }
        }
         **/

//        String identity = appUserIdentityService.queryUserIdentityString(userInfo.getCompanyId(),userInfo.getId());
//        if(StringUtils.isNotEmpty(identity)){
//            userInfo.setIdentity(identity);
//        }

        appUserIdentityService.queryUserIdentityString(userInfo.getCompanyId(),userInfo.getId(), userInfo);

        return userInfo;
    }


    private static UserOutDTO copyUserDTO(AppUserInfo userInfo){
        return AppUserUtils.copyUserDTO(userInfo);
    }

}
